#ifndef ADBUTILS_H
#define ADBUTILS_H
#include <QObject>
#include <QMutex>
#include <QDebug>

#define ABI_PROP  "ro.product.cpu.abi"
#define SDK_PROP  "ro.build.version.sdk"
#define PRE_PROP  "ro.build.version.preview_sdk"
#define REL_PROP  "ro.build.version.release"

#define MINI_CAP_BINARY_NAME  "minicap";
#define MINI_CAP_BINARY_NAME_NO_PIE  "minicap-nopie";
#define MINI_CAP_BINARY_DIR  QDir::currentPath().append("/minicap_binary/minicap/bin/")

#define MINI_CAP_LIB_DIR  QDir::currentPath().append("/minicap_binary/minicap/shared/")
#define MINI_CAP_LIB_NAME "minicap.so"

#define MINI_CAP_WM_SIZE_COMMAND  "wm size"
#define MINI_EXECUTE_DEVICE_DIR  QString("/data/local/tmp/minicap-devel/")

#define MINI_CAP_EXECUTE_BASE_CMD  QString("LD_LIBRARY_PATH=").append(MINI_EXECUTE_DEVICE_DIR).append(" ") \
    .append(MINI_EXECUTE_DEVICE_DIR)
// minicap -P 720x1280@360x640/0"

// mini touch
#define MINI_TOUCH_BINARY_DIR  QDir::currentPath().append("/minitouch_binary/minitouch/")
#define MINI_TOUCH_BINARY_NAME  "minitouch"

class AdbUtils : public QObject
{

   Q_OBJECT
public:
    explicit AdbUtils(QObject *parent = 0);
    enum KeyCode{
        home = 3,
        power = 26,
        back = 4,
        vol_up = 24,
        vol_down = 25,
        menu = 82,
        app_switch = 187
    };

    static AdbUtils* getInstance();

    static void mkdir(QString dir) {
        getInstance()->excute_adb(QString("mkdir ").append(dir), true);
    }

    static void push(QString src, QString dst) {
        QString cmd = QString("push ").append(src).append(" ").append(dst);
        getInstance()->excute_adb(cmd, false);
    }

    static void chmod(QString mode, QString src) {
        QString cmd = QString("chmod ").append(mode).append(" ").append(src);
        getInstance()->excute_adb(cmd, true);
    }

    static void sendKey(KeyCode code) {
       getInstance()->adb_sendKey(code);
    }

    static QString getProp(QString prop) {
       return getInstance()->adb_getprop(prop);
    }

    static int getDevicesNum() {
       return getInstance()->adb_devices();
    }

    static QString excute(QString cmd, int shell=false) {
       return getInstance()->excute_adb(cmd, shell);
    }

    static int getDisHeight(int width) {
        int w, h;
        return getDisHeight(width, w, h);
    }

    static int getDisHeight(int width, int &dWidth, int &dHeight) {
        QString size = getDeviceSize();
        QStringList sizes = size.split("x");
        dWidth= sizes.value(0).trimmed().toInt();
        dHeight = sizes.value(1).trimmed().toInt();
        if (width <= 0) width = 360;
        return width * dHeight / dWidth;
    }

    static QString getDeviceSize() {
        QString ret = AdbUtils::excute(MINI_CAP_WM_SIZE_COMMAND, true);
        return ret.split(":").value(1).trimmed();
    }

private:
    static QMutex mutex;
    static QAtomicPointer<AdbUtils> instance;

    QString excute_adb(QString cmd, bool shell=false);

    QString adb_getprop(QString prop) {
        QString cmd = QString("shell getprop ").append(prop);
        return excute_adb(cmd).simplified();
    }

    void adb_sendKey(KeyCode code) {
        QString cmd = QString("shell input keyevent ").append(QString::number(code));
        excute_adb(cmd);
    }

    int adb_devices() {
        QString ret = excute_adb("devices");
        if (ret.length() <= 0) {
             return -1;
        }
        int size = 0;
        QStringList list = ret.split("\n");
        for (QString device : list) {
            device = device.replace("\n", "");
            QStringList devices = device.split("\tdevice");
            if (devices.size() >= 2){
                size++;
            }
        }
        return size;
    }
};

#endif // ADBUTILS_H
